package com.codefish.framework.spring.aop.framework.cglib;


import com.codefish.framework.spring.aop.IMethodMatcher;
import com.codefish.framework.spring.core.utils.AssertUtils;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/** 使得aopalliance的方法拦截器适配cglib的方法拦截器
 * @author <a href='https://gitee.com/hzf2281'>codefish</a>
 * @version 1.0.0
 * @since 2022/10/17 下午 07:13
 */
public class MethodInterceptorAdapter implements MethodInterceptor {
    org.aopalliance.intercept.MethodInterceptor methodInterceptor;
    IMethodMatcher methodMatcher;

    public MethodInterceptorAdapter(org.aopalliance.intercept.MethodInterceptor methodInvocation, IMethodMatcher methodMatcher) {
        AssertUtils.notNull(methodInvocation, "methodInvocation不能为null");
        AssertUtils.notNull(methodMatcher, "methodMatcher不能为null");
        this.methodInterceptor = methodInvocation;
        this.methodMatcher = methodMatcher;
    }

    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {

        if (methodMatcher.matches(method, getTargetClassFromProxyObject(object))) {
            return methodInterceptor.invoke(new CglibMethodInvocation(object, method, args, proxy));
        }
        return proxy.invokeSuper(object, args);
    }

    /**
     * 获取cglib生成的代理对象实例的被代理对象的类对象
     * @param proxy 代理对象实例
     * @return 被代理的对象的类对象
     */
    private Class<?> getTargetClassFromProxyObject(Object proxy){
        //根据cglib实现原理，应该返回代理对象的父类对象
        return proxy.getClass().getSuperclass();
    }
}
